home *** CD-ROM | disk | FTP | other *** search
/ Hardcore Gamer Resource Kit / Hardcore Gamer Resource Kit - Disc 3.iso / screensavers / saver17.zip / VoodooLights / Sources / clip.c < prev    next >
C/C++ Source or Header  |  1997-07-16  |  7KB  |  298 lines

  1. /*------------------------------------------------------/
  2. /                                                        /
  3. /    Copyright 1997, SΘrgio Durte <smd@di.fct.unl.pt>    /
  4. /                                                        /
  5. /------------------------------------------------------*/
  6.  
  7.  
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11.  
  12. #include <math.h>
  13. #include <glide.h>
  14.  
  15. #include "defines.h"
  16. #include "hw.h"
  17. #include "mat.h"
  18. #include "cam.h"
  19. #include "clip.h"
  20.  
  21. #define clp_MAX_VERTEX  40 
  22.  
  23. extern Bool wireFrame ;
  24.  
  25. static Vector Vm[ clp_MAX_VERTEX ] ;
  26.  
  27. static Vector *Vb[ clp_MAX_VERTEX ] ;
  28.  
  29. static int nM ;
  30.  
  31.  
  32. static void clp_ClipZ_MinusW( int dims, int nVi, Vector *Vi[], int *nVo, Vector *Vo[] )
  33. {
  34.     int d, j, n = 0 ;
  35.  
  36.     for( j = 0 ; j < nVi ; j++ ){
  37.         Vector *vp = Vi[j] ;
  38.         Vector *vq = Vi[j+1] ;
  39.         XYZW *p = (XYZW *)vp ;
  40.         XYZW *q = (XYZW *)vq ;    
  41.         
  42.         if( p->z < -p->w ) {      /* falha */
  43.             if( q->z > -q->w ) {  /* passa */
  44.                 Float lambda = -(p->z + p->w) / (q->z - p->z + q->w - p->w ) ;
  45.                 Vector *M = & Vm[ nM++ ] ;
  46.                 
  47.                 for( d = 0 ; d < dims ; d++ )
  48.                     (*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
  49.             
  50.                 Vo[n++] = M ;
  51.             }
  52.         } else {                
  53.             Vo[n++] = vp ;       /* passa */
  54.             if( q->z < -q->w ) { /* falha */
  55.                 Float lambda = -(p->z + p->w) / (q->z - p->z + q->w - p->w ) ;
  56.                 Vector *M = & Vm[ nM++ ] ;
  57.         
  58.                 for( d = 0 ; d < dims ; d++ )
  59.                     (*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d] ) ;
  60.  
  61.                 Vo[n++] = M ;            }
  62.         }
  63.     }
  64.     Vo[n] = Vo[0] ; /* sentinela */
  65.     *nVo = n ;
  66. }
  67.  
  68.  
  69. static void clp_ClipZ_ZER0( int dims, int nVi, Vector *Vi[], int *nVo, Vector *Vo[] )
  70. {
  71.     int j, d, n = 0 ;
  72.  
  73.     for( j = 0 ; j < nVi ; j++ ){
  74.         Vector *vp = Vi[j] ;
  75.         Vector *vq = Vi[j+1] ;
  76.         XYZW *p = (XYZW *)vp ;
  77.         XYZW *q = (XYZW *)vq ;
  78.  
  79.         if( p->z > 0.0f ) {      /* falha */
  80.             if( q->z < 0.0f ) {  /* passa */
  81.         
  82.                 Float lambda = -p->z / (q->z - p->z ) ;
  83.                 Vector *M = & Vm[ nM++ ] ;
  84.         
  85.                         
  86.                 for( d = 0 ; d < dims ; d++ )
  87.                     (*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
  88.  
  89.  
  90.                 Vo[n++] = M ;    
  91.             }
  92.         } else {
  93.             Vo[n++] = vp ;
  94.             if( q->z > 0.0f ) { /* falha */
  95.                 Float lambda = -p->z / (q->z - p->z ) ;
  96.                 Vector *M = & Vm[ nM++ ] ;
  97.         
  98.                         
  99.                 for( d = 0 ; d < dims ; d++ )
  100.                     (*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
  101.  
  102.                 Vo[n++] = M ;
  103.             }
  104.         }
  105.     }
  106.     Vo[n] = Vo[0] ; /* sentinela */
  107.     *nVo = n ;
  108. }
  109.  
  110. static void clp_ClipX_MinusW( int dims, int nVi, Vector *Vi[], int *nVo, Vector *Vo[] )
  111. {
  112.     int j, d, n = 0 ;
  113.     for( j = 0 ; j < nVi ; j++ ){
  114.         Vector *vp = Vi[j] ;
  115.         Vector *vq = Vi[j+1] ;
  116.         XYZW *p = (XYZW *)vp ;
  117.         XYZW *q = (XYZW *)vq ;
  118.  
  119.         if( p->x < -p->w ) {      /* falha */
  120.             if( q->x > -q->w ) {  /* passa */
  121.                 Vector *M = & Vm[ nM++ ] ;
  122.                 Float lambda = -(p->x + p->w) / (q->x - p->x + q->w - p->w ) ;
  123.             
  124.                 for( d = 0 ; d < dims ; d++ )
  125.                     (*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
  126.  
  127.                 Vo[n++] = M ;    
  128.             }
  129.         } else {                
  130.             Vo[n++] = vp ;        /* passa */
  131.             if( q->x < -q->w ) { /* falha */
  132.                 Vector *M = & Vm[ nM++ ] ;
  133.                 Float lambda = -(p->x + p->w) / (q->x - p->x + q->w - p->w ) ;
  134.             
  135.                 for( d = 0 ; d < dims ; d++ )
  136.                     (*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
  137.  
  138.                 Vo[n++] = M ;    
  139.             }
  140.         }
  141.     }
  142.     Vo[n] = Vo[0] ; /* sentinela */
  143.     *nVo = n ;
  144. }
  145.  
  146. static void clp_ClipY_MinusW( int dims, int nVi, Vector *Vi[], int *nVo, Vector *Vo[] )
  147. {
  148.     int j, d, n = 0 ;
  149.     for( j = 0 ; j < nVi ; j++ ){
  150.         Vector *vp = Vi[j] ;
  151.         Vector *vq = Vi[j+1] ;    
  152.         XYZW *p = (XYZW *)vp ;
  153.         XYZW *q = (XYZW *)vq ;
  154.         
  155.         if( p->y < -p->w ) {      /* falha */
  156.             if( q->y > -q->w ) {  /* passa */
  157.                 Float lambda = -(p->y + p->w) / (q->y - p->y + q->w - p->w ) ;
  158.                 Vector *M = & Vm[ nM++ ] ;
  159.         
  160.                 for( d = 0 ; d < dims ; d++ )
  161.                     (*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
  162.  
  163.                 Vo[n++] = M ;    
  164.             }
  165.         } else {                
  166.             Vo[n++] = vp ;        /* passa */
  167.             if( q->y < -q->w ) { /* falha */
  168.                 Float lambda = -(p->y + p->w) / (q->y - p->y + q->w - p->w ) ;
  169.                 Vector *M = & Vm[ nM++ ] ;
  170.     
  171.                 for( d = 0 ; d < dims ; d++ )
  172.                     (*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
  173.  
  174.                 Vo[n++] = M ;
  175.             }
  176.         }
  177.     }
  178.     Vo[n] = Vo[0] ; /* sentinela */
  179.     *nVo = n ;
  180. }
  181. static void clp_ClipX_W( int dims, int nVi, Vector *Vi[], int *nVo, Vector *Vo[] )
  182. {
  183.     int j, d, n = 0 ;
  184.     for( j = 0 ; j < nVi ; j++ ){
  185.         Vector *vp = Vi[j] ;
  186.         Vector *vq = Vi[j+1] ;
  187.         XYZW *p = (XYZW *)vp ;
  188.         XYZW *q = (XYZW *)vq ;
  189.  
  190.         if( p->x > p->w ) {      /* falha */
  191.             if( q->x < q->w ) {  /* passa */
  192.                 Float lambda = (p->x - p->w) / (-(q->x - p->x) + q->w - p->w ) ;
  193.                 Vector *M = & Vm[ nM++ ] ;
  194.         
  195.                 for( d = 0 ; d < dims ; d++ )
  196.                     (*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
  197.  
  198.                 Vo[n++] = M ;
  199.             }
  200.         } else {                
  201.             Vo[n++] = vp ;       /* passa */
  202.             if( q->x > q->w ) { /* falha */
  203.                 Float lambda = (p->x - p->w) / (-(q->x - p->x) + q->w - p->w ) ;
  204.                 Vector *M = & Vm[ nM++ ] ;
  205.         
  206.                 for( d = 0 ; d < dims ; d++ )
  207.                     (*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
  208.  
  209.                 Vo[n++] = M ;
  210.             }
  211.         }
  212.     }
  213.     Vo[n] = Vo[0] ; /* sentinela */
  214.     *nVo = n ;
  215. }
  216.  
  217. static void clp_ClipY_W( int dims, int nVi, Vector *Vi[], int *nVo, Vector *Vo[] )
  218. {
  219.     int j, d, n = 0 ;
  220.     for( j = 0 ; j < nVi ; j++ ){
  221.         Vector *vp = Vi[j] ;
  222.         Vector *vq = Vi[j+1] ;    
  223.         XYZW *p = (XYZW *)vp ;
  224.         XYZW *q = (XYZW *)vq ;
  225.         
  226.         if( p->y > p->w ) {      /* falha */
  227.             if( q->y < q->w ) {  /* passa */
  228.                 Float lambda = (p->y - p->w) / (-(q->y - p->y) + q->w - p->w ) ;
  229.                 Vector *M = & Vm[ nM++ ] ;
  230.         
  231.                 for( d = 0 ; d < dims ; d++ )
  232.                     (*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
  233.  
  234.                 Vo[n++] = M ;    
  235.             }
  236.         } else {                
  237.             Vo[n++] = vp ;        /* passa */
  238.             if( q->y > q->w ) {  /* falha */
  239.                 Float lambda = (p->y - p->w) / (-(q->y - p->y) + q->w - p->w ) ;
  240.                 Vector *M = & Vm[ nM++ ] ;
  241.         
  242.                 for( d = 0 ; d < dims ; d++ )
  243.                     (*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
  244.  
  245.                 Vo[n++] = M ;    
  246.             }
  247.         }
  248.     }
  249.     Vo[n] = Vo[0] ; /* sentinela */
  250.     *nVo = n ;
  251. }
  252.  
  253. static void clp_DrawPolygon( int n, XYZWRGBAST *v[])
  254. {
  255.     int i, ilist[ clp_MAX_VERTEX ] ;
  256.     GrVertex vtx[ clp_MAX_VERTEX ] ;
  257.  
  258.     if( n < 3 ) return ;
  259.     for( i = 0 ; i < n ; i++ ) {
  260.         ilist[i] = i ;
  261.         cam_XYZWRGBAST2Vertex( v[i], & vtx[i] ) ;
  262.     }
  263.     ilist[n] = ilist[0] ; /* sentinela */
  264.     
  265.     grDrawPolygon(n, ilist, vtx ) ;
  266. }
  267.  
  268. Bool clp_PointVisible( XYZW *p )
  269. {
  270.     if( p->w < 0.0 || p->x < -p->w || p->x > p->w || p->y < -p->w || p->y > p->w || p->z < -p->w || p->z > 0.0 ) return False ;
  271.     else return True ;
  272. }
  273.  
  274. void clp_ClipPolygonRef( int dims, int nVi, Vector *Vi[], int *nVo, Vector *Va[] )
  275. {
  276.     int n ;
  277.     
  278.     nM = 0 ;
  279.     
  280.     Vi[nVi ] = Vi[0] ; /* sentinela */
  281.  
  282.     clp_ClipX_MinusW( dims, nVi, Vi, & n, Vb ) ;
  283.     
  284.     clp_ClipX_W( dims, n, Vb, & n, Va ) ;
  285.     
  286.     clp_ClipY_MinusW( dims, n, Va, & n, Vb ) ;
  287.     
  288.     clp_ClipY_W( dims, n, Vb, & n, Va ) ;
  289.  
  290.     clp_ClipZ_MinusW( dims, n, Va, & n, Vb ) ;
  291.     
  292.     clp_ClipZ_ZER0( dims, n, Vb, & n, Va) ;
  293.  
  294.     clp_DrawPolygon( n, (XYZWRGBAST **)Va ) ;
  295.  
  296.     *nVo = n ;
  297. }
  298.